#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "lz/lz78.h"

#define ALGO_huffman	"huff"
#define ALGO_LZ77		"lz77"
#define ALGO_LZ78		"lz78"
#define ALGO_LZW		"lzw"
#define ALGO_INFLATE	"defl"

typedef struct {
	char * inputFile;
	char * outputFile;
	char compression;
	char algo[5];
} options_t;

char prefix[12] = "plopplop";

//-----------------------------------------------------------------------------
void printUsage()
//-----------------------------------------------------------------------------
{
	printf("Usage : %s <inputFile> <outputFile> ACTION [ALGORITHME]\n",prefix);
	printf("ACTION :\n \
			-c\tCompression\n\
			-d\tDécompression\n\
			\n\
			ALGORITHME :\n \
			-t algo\n\
			Type d'algo utilisé. Cette option n'est utile uniquement lorsque l'option\n\
			-c est activée. La valeur algo peut prendre les valeurs suivantes :\n\
			huff :  Algorithme de huffman.\n\
			lz77 :  LZ77.\n\
			lz78 :  LZ78.\n\
			lzw  :  LZW.\n\
			defl :  Algiorithme Deflate/Inflate (LZ77+Huffman)\n\
	\n");
}

//-----------------------------------------------------------------------------
void readopts(options_t * opts, int argc, char ** argv)
//-----------------------------------------------------------------------------
//bidule <input_file> [ <output_file> [-cd -t algo]]
{
	int i;

	opts->inputFile = argv[1];//strdup(argv[1]);
	opts->outputFile = argv[2];//strdup(argv[2]);
	opts->compression = '\0';
	strcpy(opts->algo,"lz77");

	for(i = 3; i < argc; i++)
	{
		if( argv[i][0] == '-' )
		{
			switch( argv[i][1] )
			{
				case 'c':
					//compression
					if(!opts->compression) opts->compression = 'c';
					else
					{
						printf("%s: les arguments -c et -d sont incompatibles\n",prefix);
						exit(EXIT_FAILURE);
					}
					break;
				case 'd':
					//decompression
					if(!opts->compression) opts->compression = 'd';
					else
					{
						printf("%s: les arguments -c et -d sont incompatibles\n",prefix);
						exit(EXIT_FAILURE);
					}
					break;
				case 't':
					//type de compression {huff, lz77, lz78, ...}
					strncpy(opts->algo,argv[++i],5);
					break;
				default:
					printf("%s: argument inconnu (%s)\n", prefix, argv[i]);
					break;
			};
		} else
		{
			printf(" %s : argument invalide\n", argv[i]);
			exit(EXIT_FAILURE);
		}
	}

	if(!opts->compression){
		printUsage();
		exit(EXIT_FAILURE);
	}
}

//-----------------------------------------------------------------------------
int main(int argc, char ** argv)
//-----------------------------------------------------------------------------
{
	options_t opts;
	FILE * fin;
	FILE * fout;
	char	id[5];
	id[4]='\0';

	strncpy(prefix, argv[0], 12);

	readopts(&opts, argc, argv);


	if(!(fin =fopen(opts.inputFile,"rb"))){
		printf("%s: fopen(): %s (%s)\n",prefix,strerror(errno),opts.inputFile);
		return errno;
	}

	if(!(fout=fopen(opts.outputFile,"w+b"))){
		printf("%s: fopen(): %s (%s)\n",prefix,strerror(errno),opts.outputFile);
		return errno;
	}

	//printf("inputfile = %s\noutputfile = %s\n",opts.inputFile, opts.outputFile);

	if(opts.compression == 'c')
	{
		//CHOIX DE L'ALGO DE COMPRESSION

		if(!strncmp(ALGO_huffman,opts.algo,5)){
			printf("%s: pas encore implémenté (%s)\n",prefix,opts.algo);
			return EXIT_FAILURE;

		}else if(!strncmp(ALGO_LZ77,opts.algo,5)){
			printf("%s: pas encore implémenté (%s)\n",prefix,opts.algo);
			return EXIT_FAILURE;

		}else if(!strncmp(ALGO_LZ78,opts.algo,5)){
			printf("Compression LZ78 GOGOGO !\n");
			LZ78_compress(fout,fin);

		}else if(!strncmp(ALGO_LZW,opts.algo,5)){
			printf("%s: pas encore implémenté (%s)\n",prefix,opts.algo);
			return EXIT_FAILURE;

		}else if(!strncmp(ALGO_INFLATE,opts.algo,5)){
			printf("%s: pas encore implémenté (%s)\n",prefix,opts.algo);
			return EXIT_FAILURE;

		}else{
			printf("%s: Algorithme inconnu (%s)\n",prefix,opts.algo);
			return EXIT_FAILURE;
		}
	}else{
		// DECOMPRESSION
		printf("décompression ");
		fread(id, 4, 1, fin);
		if(ferror(fin))
		{
			printf("%s: fread(): %s (%s)\n",prefix,strerror(errno),opts.inputFile);
			return errno;
		}
		rewind(fin);
		if(!strncmp(id,LZ78ID,4))
		{
			printf("LZ78 GOGOGO !\n");
			LZ78_decompress(fout,fin);

		//else if( !strncmp(id, LZ77, 4) ){
			//LZ77_decompress(fout,fin);
		}else{
			printf("%s: %s type de fichier inconnu\n",prefix, opts.inputFile);
			return EXIT_FAILURE;
		}

	}

	//free(opts.inputFile);
	//free(opts.outputFile);
	fclose(fin);
	fclose(fout);

	return EXIT_SUCCESS;
}

//
